﻿using System;
using System.Net;
using System.Text;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;

namespace Skimpt3
{
    public class PostFile
    {
        private Hashtable FormElements;
        private HttpWebRequest Request;
        private Stream FileStream;

        private string CONTENT_BOUNDARY = "---------------------------265001916915724";

        public string ContentMIMEType;
        public string FormURL;
        public string FileName;
        public string Response;
        public Stream ResponseStream;
        public string FileBoxName;

        public PostFile(string Url, string strFileName)
        {
            FormElements = new Hashtable();
            FormURL = Url;
            Request = (HttpWebRequest)WebRequest.Create(Url);
            FileStream = new MemoryStream();
            FileName = strFileName;
        }

        public void Send(Image image)
        {
            System.Net.ServicePointManager.Expect100Continue = false;

            //Assign the request here too, just in case
            Request = (HttpWebRequest)WebRequest.Create(FormURL);

            Request.Method = WebRequestMethods.Http.Post;
            Request.AllowWriteStreamBuffering = true;
            Request.ProtocolVersion = HttpVersion.Version11;
            Request.Headers.Add("Pragma", "no-cache");
            Request.KeepAlive = true;
            Request.Headers.Add("Keep-Alive", "300");
            Request.ContentType = "multipart/form-data; boundary=---------------------------265001916915724";
            Request.Accept = "image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, application/x-shockwave-flash, */*";
            Request.Referer = FormURL;
            Request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Tablet PC 2.0; InfoPath.2; Zune 3.0)";
            Request.Headers.Add("Accept-Encoding", "gzip, deflate");
            Request.Headers.Add("Accept-Language", "en-GB");
            Request.CookieContainer = new CookieContainer();
            Request.ContentLength = GetFormElements().Length + GetFileHeader().Length + GetFileTrail().Length + ConvertImageToByteArray(image).Length;

            try
            {
                FileStream = Request.GetRequestStream();
            }
            catch (Exception ex)
            {
                throw ex;
            }

            //Must be done in this order for stream to write properly:
            //----
            //Form elements
            //Image
            //File trailer
            //----
            try
            {
                WriteStringToStream(FileStream, GetFormElements());
                WriteImageToStream(FileStream, image);
                WriteStringToStream(FileStream, GetFileTrail());
            }
            catch (Exception ex)
            {
                throw ex;
            }

            WebResponse resp;
            StreamReader SR;
            try
            {
                resp = (HttpWebResponse)Request.GetResponse();
                SR = new StreamReader(resp.GetResponseStream());
                FileStream.Close();
                ResponseStream = resp.GetResponseStream();     
                Response = SR.ReadToEnd();
                Request = null;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void CloseStream(Stream FileStream)
        {
            byte[] BytesToWrite = Encoding.ASCII.GetBytes("--"+CONTENT_BOUNDARY+"--");
            FileStream.Write(BytesToWrite, 0, BytesToWrite.Length);
        }

        private Byte[] ConvertImageToByteArray(Image img)
        {
            //Method taken from http://www.csharp-station.com/Articles/Thumbnails.aspx and adapted
            MemoryStream memStream = new MemoryStream();
            img.Save(memStream, System.Drawing.Imaging.ImageFormat.Png);
			
            return memStream.ToArray();
        }

        public void AddFormElement(string ElementName, string ElementValue)
        {
            FormElements[ElementName] = ElementValue;
        }

        private string GetFormElements()
        {
            string str = "";
            IDictionaryEnumerator myEnumerator = FormElements.GetEnumerator();
            while (myEnumerator.MoveNext())
            {
                str += "--"+CONTENT_BOUNDARY + "\r\n" +
                    "Content-Disposition: form-data; name=" + myEnumerator.Key +
                    "\r\n\r\n" +
                    myEnumerator.Value +"\r\n";
            }
            return str;
        }

        private string GetFileTrail()
        {
            string FileTrail = "\r\n--" + CONTENT_BOUNDARY + "--";
            return FileTrail;
        }

        private void WriteStringToStream(Stream stream, string String)
        {
            byte[] PostData = System.Text.Encoding.ASCII.GetBytes(String);
            stream.Write(PostData, 0, PostData.Length);
        }

        private string GetFileHeader()
        {
            string head = "--" + CONTENT_BOUNDARY + "\r\n" +
                          "Content-Disposition: form-data; name=\"" + FileBoxName + "\"; filename=\"" + FileName + "\"\r\n" +
                          "Content-Type: " + ContentMIMEType + "\r\n\r\n";
            return head;
        }

        private void WriteImageToStream(Stream Stream, Image img)
        {
            byte[] ByteArray = ConvertImageToByteArray(img);

            byte[] header = Encoding.ASCII.GetBytes(GetFileHeader());

            Stream.Write(header, 0, header.Length);
            Stream.Write(ByteArray, 0, ByteArray.Length);
        }
    }
}
